Object.prototype.hasOwnProperty = function(property) {
    return typeof this[property] !== 'undefined';
};

(function() {
	var MAX_HARVEST_DISTANCE = 999999;

	var STATE_HARVEST = 1;
	var STATE_ASKING_NAMES = 2;
	var STATE_PLEASE_START = 3;

	var canvas, ctx, onError, onSuccess, updateCamera, sendPhotoForPredict, video, ws;
	var minDistance = MAX_HARVEST_DISTANCE;
	var nadaCount = 0, photosSended = 0;
	var state = STATE_PLEASE_START;
	var x=0, y=0, width=0, height=0;
	var lastPhotoSended = null;
	var responseReceived = true;

	var userIndex = 0;
	var usersDetected = {};
	var sortUsers = [];

	var intervalPredict = null;
	var intervalConnect = null;
	var timeoutMarkSucess = null;

	var startMarksDiv = $('#startmarks');
	var buttonsDiv = $('#buttons');
	var entsalDiv = $('#entsal');
	var titleFace = $('#title-face');
	var faceNameTitle = $('#name-of-face');
	var prettyprint = $('#prettyprint');

	var lastMark1 = $('a#last1');
	var lastMark2 = $('a#last2');
	var lastMark3 = $('a#last3');
	var lastMark4 = $('a#last4');
	var lastMark5 = $('a#last5');

	var lastMarkings = [lastMark1, lastMark2, lastMark3, lastMark4, lastMark5];
	for(var i=0; i<5; i++){ lastMarkings[i].click(function(){return false;}); }

	var btnMarcar = $('#btnmarcar');

	var btnSi = $('#sisoy');
	var btnNo = $('#nosoy');

	var btnEntrada = $('#btnentrada');
	var btnSalida = $('#btnsalida');
	var btnCancelar = $('#btncancelar');

	buttonsDiv.hide();
	entsalDiv.hide();
	prettyprint.hide();
	startMarksDiv.show();

	video = document.querySelector('video');
	canvas = document.querySelector('canvas');
	ctx = canvas.getContext('2d');
	ctx.strokeStyle = '#ff0';
	ctx.lineWidth = 2;

	onError = function(e){
		alert("Su navegador no tiene acceso a la cámara.");
	};

	onSuccess = function(localMediaStream) {
		video.src = webkitURL.createObjectURL(localMediaStream);
		tryConnectWS();
		setInterval(updateCamera, 1);
	};

	updateCamera = function() {
		ctx.drawImage(video, 0, 0, 320, 240);

		if(state == STATE_HARVEST){
			if(width > 0 && height > 0){
				$('#canvasvideo').css('border', '8px solid yellowgreen');
			}else{
				$('#canvasvideo').css('border', '8px solid red');
			}
		}else{
			$('#canvasvideo').css('border', '8px solid transparent');
		}

		//ctx.strokeRect(x, y, width, height);
	};

	sendPhotoForPredict = function(){
		if(state == STATE_HARVEST){
			if(responseReceived){
				responseReceived = false;
				return canvas.toBlob(function(blob) {
					lastPhotoSended = blob;
					return ws.send(blob);
				}, 'image/jpeg');
			}
		}else{
			x = 0; y = 0; width = 0; height = 0;
		}
		return false;

	};

	tryConnectWS = function(){
		if(ws == null){
			startMarksDiv.hide();
			titleFace.text("Conectando con el servidor...");
			ws = new WebSocket("ws://" + location.host + "/predict");
			ws.onopen = onopen;
			ws.onclose = onclose;
			ws.onmessage = onmessage;
		}
	};

	sendLogToServer = function(success){
		var errorNames = [];
		if(userIndex > 0){
			for(var i=0; i<userIndex; i++){
				errorNames.push(sortUsers[i][1].username);
			}
		}

		/*
		console.log("USERNAME: " + sortUsers[userIndex][1].username);
		console.log("DISTANCE: " +  Math.round(sortUsers[userIndex][1].distance));
		console.log("ASKNUMBER: " + userIndex);
		console.log("ERROR NAMES: " + errorNames);
		console.log("BLOB PHOTO: " + sortUsers[userIndex][1].minPhoto);
		*/

		var formData = new FormData();

		if(success){
			formData.append('username', sortUsers[userIndex][1].username);
			formData.append('distance', Math.round(sortUsers[userIndex][1].distance));
			formData.append('asknumber', userIndex);
			formData.append('errornames', errorNames);
			formData.append('blobphoto', sortUsers[userIndex][1].minPhoto);
		}else{
			formData.append('username', "none");
			formData.append('distance', Math.round(sortUsers[0][1].distance));
			formData.append('asknumber', userIndex);
			formData.append('errornames', errorNames);
			formData.append('blobphoto', sortUsers[0][1].minPhoto);
		}

		$.ajax({
			type: 'POST',
			url: '/logs/save',
			data: formData,
			processData: false,
			contentType: false
		}).done(function(data){
			/*console.log(data);*/
		})
	};

	onopen = function(){
		clearInterval(intervalConnect);
		restart();
		intervalPredict = setInterval(sendPhotoForPredict, 250);
	};

	onclose = function(){
		ws = null;
		clearInterval(intervalPredict);
		restart();
		titleFace.text("Conectando con el servidor...");
		intervalConnect = setInterval(tryConnectWS, 3500)
	};

	onmessage = function(e){
		var data = JSON.parse(e.data);

		if(data){
			if(data.hasOwnProperty("face")){
				uidString = data.face.username;

				if(state == STATE_HARVEST){

					//DISTANCE MARGIN ERROR CHECK
					if(data.face.distance <= 110){
						x = data.face.coords.x; y = data.face.coords.y;
						width = data.face.coords.width; height = data.face.coords.height;

						if(usersDetected.hasOwnProperty(uidString)){
							if(usersDetected[uidString].distance > data.face.distance){
								usersDetected[uidString].distance = data.face.distance;
								usersDetected[uidString]["minPhoto"] = lastPhotoSended;
							}
						}else{
							usersDetected[uidString] = data.face;
							usersDetected[uidString]["minPhoto"] = lastPhotoSended;
						}

						photosSended++;

						if(photosSended >= 7){
							state = STATE_ASKING_NAMES;

							sortUsers = [];
							for(var uid in usersDetected)
								  sortUsers.push([uid, usersDetected[uid]])
							sortUsers.sort(function(a, b) {return a[1].distance - b[1].distance});

							if(sortUsers.length > 0){
								userIndex = 0;
								titleFace.text("¿Es usted?");
								faceNameTitle.text(sortUsers[userIndex][1].name + " - " + Math.round(sortUsers[userIndex][1].distance));
								startMarksDiv.hide();
								buttonsDiv.show();
							}else{
								restart();
							}
						}
					}
				}
			}else if(data.hasOwnProperty("qr")){
				state = STATE_ASKING_NAMES;
				sortUsers = [[uidString, data.qr]];

				userIndex = 0;
				titleFace.text("¿Es usted?");
				faceNameTitle.text(sortUsers[userIndex][1].name);
				x = 0; y = 0; width = 0; height = 0;
				buttonsDiv.hide();
				prettyprint.hide();
				startMarksDiv.hide();
				entsalDiv.show("slow");
			}
		}else{
			nadaCount++;
			x = 0; y = 0; width = 0; height = 0;
			if(nadaCount >= 12 && state == STATE_HARVEST){
				restart();
			}
		}

		responseReceived = true;
	};

	btnNo.click(function(event){
		event.preventDefault();

		userIndex++;

		if(userIndex < sortUsers.length){
			titleFace.text("¿Es usted?");
			faceNameTitle.fadeOut(500, function() {
				$(this).text(sortUsers[userIndex][1].name + " - " + Math.round(sortUsers[userIndex][1].distance)).fadeIn(500);
			});
		}else{
			sendLogToServer(false);
			restart();
		}
	});

	btnSi.click(function(event){
		event.preventDefault();
		buttonsDiv.hide();
		entsalDiv.show("slow");
	});

	btnMarcar.click(function(event){
		event.preventDefault();
		startMarksDiv.hide();
		buttonsDiv.hide();
		entsalDiv.hide();
		state = STATE_HARVEST;
	});

	btnEntrada.click(function(event){
		event.preventDefault();

		var link = 'http://200.9.4.106/personal/wsmarcacion.php?id=' + sortUsers[userIndex][1].username + '&hash=' + sortUsers[userIndex][1].hash + '&tipo=E';
		//var link = 'http://200.9.4.106/personal/wsmarcacion.php?id=' + 'DUMMYEMP' + '&hash=' + '5404d05ca54cb6a143a7651c45c22198' + '&tipo=E';

		$.ajax({
			url: link,  //server script to process data
			type: 'GET',
			crossDomain: true,
   			dataType: 'jsonp',

			//Ajax events
			error: function(){
				buttonsDiv.hide();
				entsalDiv.hide();
				prettyprint.show();
				faceNameTitle.text("");
				titleFace.text("Error en Marcación");
				prettyprint.text("Favor contacte con el administrador\n\ndel sistema.");
				timeoutMarkSucess = setTimeout(restart, 7000);
			},
			success: function(event, xhr, settings){
				buttonsDiv.hide();
				entsalDiv.hide();
				prettyprint.show();

				if(event.result == "success"){
					titleFace.text("Marcación Completa!");
					prettyprint.text("\n\nBienvenido al DEI-LED.\n\nSu marcación de ENTRADA ha sido registrada.\n\nLes deseamos una excelente jornada.\n\n");

					sendLogToServer(true);

					timeoutMarkSucess = setTimeout(restart, 7000);

					updateLastMarkings();
				}else{
					faceNameTitle.text("");
					titleFace.text("Error en Marcación");
					prettyprint.text("Favor contacte con el administrador\n\ndel sistema.");
					timeoutMarkSucess = setTimeout(restart, 7000);
				}
			},

			//Options to tell JQuery not to process data or worry about content-type
			cache: false,
			contentType: false,
			processData: false
		});
	});

	btnCancelar.click(function(event){
		event.preventDefault();
		restart();
	});

	btnSalida.click(function(event){
		event.preventDefault();

		var link = 'http://200.9.4.106/personal/wsmarcacion.php?id=' + sortUsers[userIndex][1].username + '&hash=' + sortUsers[userIndex][1].hash + '&tipo=S';
		//var link = 'http://200.9.4.106/personal/wsmarcacion.php?id=' + 'DUMMYEMP' + '&hash=' + '5404d05ca54cb6a143a7651c45c22198' + '&tipo=S';

		$.ajax({
			url: link,  //server script to process data
			type: 'GET',
			crossDomain: true,
   			dataType: 'jsonp',

			//Ajax events
			error: function(){
				buttonsDiv.hide();
				entsalDiv.hide();
				prettyprint.show();
				faceNameTitle.text("");
				titleFace.text("Error en Marcación");
				prettyprint.text("Favor contacte con el administrador\n\ndel sistema.");
				timeoutMarkSucess = setTimeout(restart, 7000);
			},
			success: function(event, xhr, settings){
				buttonsDiv.hide();
				entsalDiv.hide();
				prettyprint.show();

				if(event.result == "success"){
					titleFace.text("Marcación Completa!");
					prettyprint.text("\n\nHasta pronto!\n\nSu marcación de SALIDA ha sido registrada.\n\nQue le vaya bien!\n\n");

					sendLogToServer(true);

					timeoutMarkSucess = setTimeout(restart, 7000);

					updateLastMarkings();
				}else{
					faceNameTitle.text("");
					titleFace.text("Error en Marcación");
					prettyprint.text("Favor contacte con el administrador\n\ndel sistema.");
					timeoutMarkSucess = setTimeout(restart, 7000);
				}
			},

			//Options to tell JQuery not to process data or worry about content-type
			cache: false,
			contentType: false,
			processData: false
		});
	});

	updateLastMarkings = function(){
		$.ajax({
			url: 'http://200.9.4.106/personal/wslistmarcacion.php',
			type: 'GET',
			crossDomain: true,
   			dataType: 'jsonp',

			//Ajax events
			success: function(event, xhr, settings){
				var data = event.data;
				var indexName = null;
				var name = null;
				var tipo = null;

				for(var i=1; i<=5; i++){
					indexName = "n" + i;
					if(data && data[i-1].hasOwnProperty(indexName)){
						if(data[i-1][indexName][0].tipo == 'E'){
							tipo = 'ENT';
						}else{
							tipo = 'SAL';
						}
						name = (data[i-1][indexName][0].nombre + "   ").split(" ");
						lastMarkings[i-1].html(i + ". " + name[0] + " " + name[1] + " " + name[2] + "<br/>&nbsp;&nbsp;&nbsp;&nbsp;" + tipo + "&nbsp;&nbsp;" + data[i-1][indexName][0].fecha);
					}else{
						lastMarkings[i-1].html(i + ". ");
					}
				}
			},

			//Options to tell JQuery not to process data or worry about content-type
			cache: false,
			contentType: false,
			processData: false
		});
	};

	restart = function(){
		nadaCount = 0;
		userIndex = 0;
		photosSended = 0;
		titleFace.text("Mire a la cámara por favor.");
		buttonsDiv.hide();
		prettyprint.hide();
		faceNameTitle.text("");
		x = 0; y = 0; width = 0; height = 0;
		usersDetected = {};
		responseReceived = true;
		lastPhotoSended = null;
		minDistance = MAX_HARVEST_DISTANCE;
		state = STATE_PLEASE_START;
		buttonsDiv.hide();
		entsalDiv.hide();
		if(ws){
			titleFace.css('color', 'rgb(25,159,247)');
			startMarksDiv.show();
		}else{
			titleFace.css('color', 'red');
			startMarksDiv.hide();
		}
		clearTimeout(timeoutMarkSucess);
	};

	updateLastMarkings();

	navigator.webkitGetUserMedia({
		'video': true,
		'audio': false
	}, onSuccess, onError);

}).call(this);
